package model

import (
	"reflect"

	"xorm.io/xorm"
)

type query interface {
	Query(DB Query) *xorm.Session
}

func Target(target any) query {
	if _t, ok := target.(query); ok {
		return _t
	}
	typ := reflect.TypeOf(target)
	switch typ.Kind() {
	case reflect.Array:
		return Target(reflect.New(typ.Elem()).Elem().Interface())
	case reflect.Slice:
		return Target(reflect.New(typ.Elem()).Elem().Interface())
	case reflect.Pointer:
		return Target(reflect.ValueOf(target).Elem().Interface())
	default:
		panic("无法处理的类型:" + typ.String())
	}
}

func QueryX(DB xorm.Interface, target any) *xorm.Session {
	return Target(target).Query(DB)
}

type QueryOp struct {
	DB     *xorm.Session
	target any
}

func (op *QueryOp) Find() error {
	return op.DB.Find(op.target)
}

func QueryZ(DB xorm.Interface, target any, h func(DB *xorm.Session) *xorm.Session) *QueryOp {
	return &QueryOp{
		DB:     h(Target(target).Query(DB)),
		target: target,
	}
}

func QueryY(DB xorm.Interface, target any) *QueryOp {
	return &QueryOp{
		DB:     Target(target).Query(DB),
		target: target,
	}
}
